/**
  * @(#)TermFactory.java
  *
  * Provide a factory interface for creating a new term 
  *
  * @author Course Scheduler Team
  * 
  * @license GNU General Public License version 3 (GPLv3)
  *
  * This file is part of Course Scheduler, an open source, cross platform
  * course scheduling tool, configurable for most universities.
  *
  * Copyright (C) 2010-2012 Course Scheduler Team
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * 
  */
package com.pollicitus.scheduler.model;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Scanner;

import com.pollicitus.scheduler.model.Term;
import com.pollicitus.scheduler.profiles.UniversityProfile;

/**
 * Provide a factory interface for creating Term objects
 * 
 * @author Course Scheduler Team
 *
 */
public class TermFactory{	

	/**
	 * The most recent revision in which this file was changed in the source control system
	 */
	public static final String _revision = "$LastChangedRevision: 539 $";
	
	/**
	 * The date on which this file was last changed and submitted to source control
	 */
	public static final String _date = "$LastChangedDate: 2011-11-19 23:14:16 -0500 (Sat, 19 Nov 2011) $";
	
	/**
	 * The user which last changed the file and committed the change to source control
	 */
	public static final String _author = "$LastChangedBy: mike@pollicitus.com $";
	
	/**
	 * The URL which can be used to access this specific file within the source control system
	 */
	public static final String _headURL = "$HeadURL: https://courseschedulerx.googlecode.com/svn/trunk/course-scheduler/course-scheduler-core/src/main/java/com/pollicitus/scheduler/model/TermFactory.java $";
	
	/**
	 * The source control file ID, comprised of the file name, latest revision, last changed date, and submitting user.
	 */
	public static final String _id = "$Id: TermFactory.java 539 2011-11-20 04:14:16Z mike@pollicitus.com $";
	
	//static variables
	private static final String yearVariable = "${YEAR}";
	private static final String codeVariable = "${TERMCODE}";
	
	//private variables
	private UniversityProfile uParms;
	
	/**
	 * Create a new term factory using the specified university profile
	 * 
	 * @param uParms
	 */
	public TermFactory(UniversityProfile uParms) {
		this.uParms = uParms;
	}
	
	/**
	 * Create a new term instance based on the term name and year
	 * 
	 * @param termName (internal or external name is valid)
	 * @param year the registration year
	 * @return build the term based on the name and year
	 */
	public Term createTerm(String termName, String year) {	
		Term term = null;

		try{
			//try to retrieve the term by internal name
			term = updateTermFields(termName, year);
		}catch(Exception e){
			//or retrieve by external name
			for(String termInternal: uParms.getUniversityTermList()) {
				if(uParms.getTermName(termInternal).compareTo(termName) == 0) { 
					term = updateTermFields(termInternal, year);
					break;
				}
			}
		}
		
		return term;
	}
	
	/**
	 * Create a new term instance using the combined term name and year
	 * 
	 * @param termNameAndYear the combined term name and year
	 * @return term built on name and year string
	 */
	public Term createTerm(String termNameAndYear){
		String[] both = termNameAndYear.split(" ");
		
		return createTerm(both[0], both[1]);
	}
	
	/**
	 * Update the internal term fields using the specified internal name
	 * and the specified registration year
	 * 
	 * @param internalName the internal term name
	 * @param year the registration year
	 * @return build a new term using the new term fields
	 */
	private Term updateTermFields(String internalName, String year){
		Term term = new Term();
		
		//get term information
		String code = uParms.getTermCode(internalName);
		String termName = uParms.getTermName(internalName);
		String format = uParms.getTermParmFormat();
		String yearFormat = uParms.getYearParmFormat();
		
		//build a calendar from the year and create the parm string
		GregorianCalendar cal = new GregorianCalendar(new Scanner(year).nextInt(), 1, 1);
		term.parm = format.replace(codeVariable, code);
		term.parm = term.parm.replace(yearVariable, new SimpleDateFormat(yearFormat).format(new Date(cal.getTimeInMillis())));
		term.name = termName + " " + year;
		
		return term;
	}
	
	/**
	 * Return a list of available terms based on the university profile
	 * 
	 * @return list of available terms (external names)
	 */
	public List<String> getAvailableTerms() {
		List<String> terms = new ArrayList<String>();
		
		for(String term: uParms.getUniversityTermList()) {
			terms.add(uParms.getTermName(term));
		}
		
		return terms;
	}
}